//--Yangxin--

`include "defines.v"

module clint(
    input  wire         clk            ,
    input  wire         reset          ,
    input  wire [63:0]  addr           ,
    input  wire [63:0]  wdata          ,
    input  wire         wr_en          , 
    output wire [63:0]  mtimecmp_o     ,
    output wire [63:0]  mtime_o        , 
    input  wire         clint_valid    ,
    //output wire         clint_ready    ,
    output wire         timer_interrupt

);

reg [63:0] mtime;
reg [63:0] mtimecmp;

always @(posedge clk) begin
    if(reset) begin
        mtime <= 64'h0;
    end
    else begin
        mtime <= mtime + 1;
    end
end

//mie
// always @(posedge clk) begin
// 	if (reset) begin
// 		// reset
// 		mie <= 64'h0;
// 	end
// 	else if (we && (waddr == CSR_MIE)) begin
// 		mie <= wdata;
// 	end
// end

//mtimecmp
wire mtimecmp_en;
assign mtimecmp_en = (addr == 64'h00000000_02004000);
assign mtimecmp_o  = mtimecmp;

reg    clint_ready_reg              ;
//assign clint_ready = clint_ready_reg;


always @(posedge clk) begin
    if(reset) begin
        mtimecmp <= 64'h0;
    end
    else if(mtimecmp_en & wr_en & clint_valid) begin
        mtimecmp <= wdata;
    end
end

// always @(posedge clk) begin
//      if(reset) begin
//          clint_ready_reg <= 1'b0;
//      end
//      else if(clint_valid) begin
//          clint_ready_reg <= 1'b1;
//      end
// end

assign timer_interrupt = (mtime >= mtimecmp);

//mtime
assign mtime_o = mtime;

endmodule